/*
 *   Copyright (C) 2009  Jens Kieselbach
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You may obtain a copy of the License at http://www.gnu.org/licenses/gpl.html
 */

package de.kieselbach.swing.border

import java.awt.Color
import java.awt.Component
import java.awt.Graphics
import java.awt.Insets
import javax.swing.border.AbstractBorder

class CustomLineBorder extends AbstractBorder {

    final def Color color
    final def boolean top
    final def boolean left
    final def boolean bottom
    final def boolean right
    final def int i1
    final def int i2
    final def int i3
    final def int i4
    final def boolean roundTopLeft
    final def boolean roundTopRight
    final def boolean roundBottomLeft
    final def boolean roundBottomRight

    CustomLineBorder() {

        this(Color.black, true, true, true, true)
    }

    CustomLineBorder(Color c) {

        this(c, true, true, true, true)
    }

    CustomLineBorder(Color c, boolean t, boolean l, boolean b, boolean r) {

        this(c, t, l, b, r, t ? 2 : 0, l ? 2 : 0, b ? 2 : 0, r ? 2 : 0, false, false, false, false)
    }

    CustomLineBorder(Color c, boolean t, boolean l, boolean b, boolean r, boolean rtl, boolean rtr, boolean rbl, boolean rbr) {

        this(c, t, l, b, r, t ? 2 : 0, l ? 2 : 0, b ? 2 : 0, r ? 2 : 0, rtl, rtr, rbl, rbr)
    }

    CustomLineBorder(Color c, boolean t, boolean l, boolean b, boolean r, int ti, int li, int bi, int ri, boolean rtl, boolean rtr, boolean rbl, boolean rbr) {

        color = c != null ? c : Color.black
        top = t
        left = l
        bottom = b
        right = r

        i1 = ti
        i2 = li
        i3 = bi
        i4 = ri

        roundTopLeft = rtl
        roundTopRight = rtr
        roundBottomLeft = rbl
        roundBottomRight = rbr
    }

    @Override
    void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {

        Color oldColor = g.color
        g.translate(x, y)
        g.color = color

        if (top) {
            g.drawLine(roundTopLeft ? 2 : 0, 0, width - (roundTopRight ? 3 : 1), 0)
        }
        if (left) {
            g.drawLine(0, roundTopLeft ? 2 : 0, 0, height - (roundBottomLeft ? 3 : 1))
        }
        if (bottom) {
            g.drawLine(roundBottomLeft ? 2 : 0, height - 1, width - (roundBottomRight ? 3 : 1), height - 1)
        }
        if (right) {
            g.drawLine(width - 1, roundTopRight ? 2 : 0, width - 1, height - (roundBottomRight ? 3 : 1))
        }

        if (roundTopLeft || roundTopRight || roundBottomLeft || roundBottomRight) {
            g.color = new Color(color.red + 10, color.green + 10, color.blue + 10)
            if (roundTopLeft) {
                g.drawLine(0, 1, 1, 0)
            }
            if (roundTopRight) {
                g.drawLine(width - 2, 0, width - 1, 1)
            }
            if (roundBottomLeft) {
                g.drawLine(0, height - 2, 1, height - 1)
            }
            if (roundBottomRight) {
                g.drawLine(width - 1, height - 2, width - 2, height - 1)
            }

            g.color = new Color(color.red + 20, color.green + 20, color.blue + 20)
            if (roundTopLeft) {
                g.drawLine(1, 1, 1, 1)
            }
            if (roundTopRight) {
                g.drawLine(width - 2, 1, width - 2, 1)
            }
            if (roundBottomLeft) {
                g.drawLine(1, height - 2, 1, height - 2)
            }
            if (roundBottomRight) {
                g.drawLine(width - 2, height - 2, width - 2, height - 2)
            }
        }

        g.translate(-x, -y)
        g.color = oldColor
    }

    @Override
    Insets getBorderInsets(Component c) {

        return new Insets(i1, i2, i3, i4)
    }

    @Override
    Insets getBorderInsets(Component c, Insets insets) {

        insets.top = i1
        insets.left = i2
        insets.bottom = i3
        insets.right = i4

        return insets
    }

    @Override
    boolean isBorderOpaque() {

        return false
    }

    // ------------------------------------------------------------------------------------------

	static def create(Color c, String corners) {
		
		create(c, corners, 2, 2, 2, 2)
	}
	
	static def create(Color c, String corners, int inset) {
		create(c, corners, inset, inset, inset, inset)
	}
	
    static def create(Color c, String corners, int tinset, int linset, int binset, int rinset) {

        def t = false;
        def l = false;
        def b = false;
        def r = false;
        def tl = false;
        def tr = false;
        def bl = false;
        def br = false;

        if (corners != null) {
            corners.toList().each() {str ->
                switch (str) {
                    case '1':
                        bl = true;
                        break;

                    case '2':
                        b = true;
                        break;

                    case '3':
                        br = true;
                        break;

                    case '6':
                        r = true;
                        break;

                    case '9':
                        tr = true;
                        break;

                    case '8':
                        t = true;
                        break;

                    case '7':
                        tl = true;
                        break;

                    case '4':
                        l = true;
                        break;
                }
            }
        }

        new CustomLineBorder(c, t, l, b, r, tinset, linset, binset, rinset,tl, tr, bl, br)
    }
}
